using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using eyeArchive.Core;
using System.Diagnostics;

namespace eyeArchive
{
	public partial class MainDialog : Form
	{
		private Kernel engine;

		public MainDialog()
		{
			InitializeComponent();
		}

		#region "MainForm Events Handlers"
		private void MainDialog_Load(object sender, EventArgs e)
		{
			DataTable dt;
			Version ver;

			ver = new Version(Application.ProductVersion);

			engine = Kernel.Instance;

			engine.OnNotify += new OnNotifyEventHandler(engine_OnNotify);
			engine.OnPreProcess += new OnPreProcessEventHandler(engine_OnPreProcess);
			engine.OnProcess += new OnProcessEventHandler(engine_OnProcess);
			engine.OnPostProcess += new OnPostProcessEventHandler(engine_OnPostProcess);

			dt = BuildActions();
			cbAction.DisplayMember = "DisplayMember";
			cbAction.ValueMember = "ValueMember";
			cbAction.DataSource = dt;

#if DEBUG
			Text = String.Format("[DEBUG] {0}", String.Format(Text, Application.ProductName, ver.Major, ver.Minor, ver.Build, ver.Revision));
#else
			Text = String.Format(Text, Application.ProductName, ver.Major, ver.Minor, ver.Build, ver.Revision);
#endif

			txtDataSource.Text = Properties.Settings.Default.DefaultDataSource;
			chkSSPI.Checked = Properties.Settings.Default.DefaultIntegratedSecurity;
			chkSqlServer.Checked = !chkSSPI.Checked;
			txtUserId.Text = (chkSSPI.Checked == true ? null : Properties.Settings.Default.DefaultUserId);
			txtPassword.Text = (chkSSPI.Checked == true ? null : Properties.Settings.Default.DefaultPassword);

		}

		private void MainDialog_HelpButtonClicked(object sender, CancelEventArgs e)
		{
			MessageBox.Show(engine.Version, string.Format("About {0}...", Application.ProductName), MessageBoxButtons.OK, MessageBoxIcon.Information);
			e.Cancel = true;
		}

		private DataTable BuildActions()
		{
			DataTable rc;

			rc = new DataTable();
			rc.Columns.Add("DisplayMember", typeof(string));
			rc.Columns.Add("ValueMember", typeof(int));

			rc.Rows.Add(Actions.None.ToString(), Actions.None);
			rc.Rows.Add(Actions.Install.ToString(), Actions.Install);
			rc.Rows.Add(Actions.Uninstall.ToString(), Actions.Uninstall);

			return rc;
		}
		#endregion

		#region "Kernel Events Handlers"
		void engine_OnNotify(object sender, eyeArchive.Core.NotifyEventArgs e)
		{
			myMessage.Text = e.Message;
			txtStatus.AppendText(String.Format("{0}: {1}\r\n", DateTime.Now, e.Message));
			myStatus.Refresh();
		}

		void engine_OnPostProcess(object sender, eyeArchive.Core.ProcessEventArgs e)
		{
			myProgress.Value = myProgress.Maximum;
			myMessage.Text = e.Message;
			myCounter.Text = string.Format("{0}/{1}", myProgress.Value, myProgress.Maximum);
			myStatus.Refresh();
			txtStatus.AppendText(string.Format("{0} - {1}\r\n", DateTime.Now.TimeOfDay, e.Message));
		}

		void engine_OnProcess(object sender, eyeArchive.Core.ProcessEventArgs e)
		{
			if (e.Value <= myProgress.Maximum)
			{
				myProgress.Value = e.Value;

			}
			myMessage.Text = e.Message;
			myCounter.Text = string.Format("{0}/{1}", myProgress.Value, myProgress.Maximum);
			myStatus.Refresh();
			txtStatus.AppendText(string.Format("{0} - {1}\r\n", DateTime.Now.TimeOfDay, e.Message));
		}

		void engine_OnPreProcess(object sender, eyeArchive.Core.ProcessEventArgs e)
		{
			myProgress.Value = 0;
			myProgress.Maximum = e.Value;
			myMessage.Text = e.Message;
			myCounter.Text = string.Format("{0}/{1}", myProgress.Value, myProgress.Maximum);
			myStatus.Refresh();
			txtStatus.AppendText(string.Format("{0} - {1}\r\n", DateTime.Now.TimeOfDay, e.Message));
		}
		#endregion

		#region "0. Wizard Management"
		private void myWizard_BeforeSwitchPages(object sender, CristiPotlog.Controls.Wizard.BeforeSwitchPagesEventArgs e)
		{
			switch (myWizard.Pages[e.OldIndex].Name)
			{
				case "pageConnection":
					myErrors.Clear();
					e.Cancel = ((cbLocalDatabase.SelectedIndex == -1) || (cbRemoteDatabase.SelectedIndex == -1));
					if (e.Cancel == true)
					{
						if (e.NewIndex >= e.OldIndex)
							if (cbLocalDatabase.SelectedIndex == -1)
								myErrors.SetError(cbLocalDatabase, "Please select a database");
							else
								myErrors.SetError(cbRemoteDatabase, "Please select a database");
						else
							e.Cancel = false;
					}
					else
					{
						Cursor = Cursors.WaitCursor;
						engine.SetLocalDatabase(cbLocalDatabase.Text);
						engine.SetRemoteDatabase(cbRemoteDatabase.Text);
						myDatabase.Text = engine.InitialCatalog;
						myServer.Text = engine.DataSource;
						mySource.DataSource = null;
						mySource.DataSource = engine.Tables.Values;
						Cursor = Cursors.Default;
					}
					if ((engine.SqlVersion == SqlVersions.Sql2000) && (e.NewIndex > e.OldIndex))
						e.NewIndex = myWizard.Pages.IndexOf(pageTables);
					break;
				case "pageDatabase":
					break;
				case "pageTables":

					if ((engine.SqlVersion == SqlVersions.Sql2000) && (e.NewIndex < e.OldIndex))
						e.NewIndex = myWizard.Pages.IndexOf(pageConnection);
					break;
				default:
					break;
			}
		}

		private void myWizard_AfterSwitchPages(object sender, CristiPotlog.Controls.Wizard.AfterSwitchPagesEventArgs e)
		{
			System.IO.Stream sysout;
			byte[] buffer;
			string script;

			switch (myWizard.Pages[e.NewIndex].Name)
			{
				case "pageDatabase":
					break;
				case "pageTables":
					if (engine.SqlVersion == SqlVersions.Sql2000)
					{
						chkUseSchema.Enabled = false;
						chkUseSchema.Checked = false;
					}
					else
					{
						lblDatabase.Text = cbLocalDatabase.Text;
					}
					break;
				case "pageSummary":
					txtSummary.Text = engine.GetSummary();
					break;
				case "pageRun":
					txtStatus.Clear();
					myWizard.Refresh();

					if (chkScriptsOnly.Checked == true)
					{
						script = engine.GetAllScripts();
						myDialog.FileName = String.Format("{0}_{1}_{2}.sql", engine.DataSource.Replace("\\", "_"), engine.InitialCatalog, DateTime.Now.ToString("yyyyMMddhhmmss"));
						if (myDialog.ShowDialog() == DialogResult.OK)
						{
							sysout = myDialog.OpenFile();
							buffer = new UTF8Encoding(true).GetBytes(script);
							sysout.Write(buffer, 0, buffer.Length);
							sysout.Flush();
							sysout.Close();
							if (MessageBox.Show("Would you like to open this file?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
								Process.Start(myDialog.FileName);
						}
					}
					else
						MessageBox.Show("This feature is not active yet");
					//engine.RunAllScripts();
					break;
				default:
					break;
			}
		}
		#endregion

		#region "1. pageConnection Events Handlers"
		private void cbLocalDatabase_DropDown(object sender, EventArgs e)
		{
			Cursor = Cursors.WaitCursor;

			cbLocalDatabase = (ComboBox)sender;

			myErrors.Clear();

			cbLocalDatabase.DataSource = null;
			cbLocalDatabase.Items.Clear();

			if (txtDataSource.Text.Length == 0)
			{
				myErrors.SetError(txtDataSource, "Please specify the data source");
			}
			else
			{
				try
				{
					SetLocalServer();
					cbLocalDatabase.DisplayMember = "Name";
					cbLocalDatabase.ValueMember = "Name";
					cbLocalDatabase.DataSource = engine.LocalDatabases;
				}
				catch (Exception ex)
				{
					MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				}
			}
			Cursor = Cursors.Default;
		}

		private void cbRemoteDatabase_DropDown(object sender, EventArgs e)
		{
			Cursor = Cursors.WaitCursor;

			cbRemoteDatabase = (ComboBox)sender;

			myErrors.Clear();

			cbRemoteDatabase.DataSource = null;
			cbRemoteDatabase.Items.Clear();

			if (txtDataSource.Text.Length == 0)
			{
				myErrors.SetError(txtDataSource, "Please specify the data source");
			}
			else
			{
				try
				{
					//SetLocalServer();
					cbRemoteDatabase.DisplayMember = "Name";
					cbRemoteDatabase.ValueMember = "Name";
					cbRemoteDatabase.DataSource = engine.RemoteDatabases;
				}
				catch (Exception ex)
				{
					MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				}
			}
			Cursor = Cursors.Default;
		}

		private void chkSSPI_CheckedChanged(object sender, EventArgs e)
		{
			txtUserId.Enabled = chkSqlServer.Checked;
			txtPassword.Enabled = chkSqlServer.Checked;
		}

		private void SetLocalServer()
		{
			engine.SetServer(txtDataSource.Text, chkSSPI.Checked, txtUserId.Text, txtPassword.Text);
			txtDataSource.Text = engine.DataSource;
		}
		#endregion

		#region "2. pageTable Events Handlers"
		private void myGrid_SelectionChanged(object sender, EventArgs e)
		{
			grpPolicy.Text = ((Table)mySource.Current).PrimaryTable;
			cbAction.SelectedValue = (int)((Table)mySource.Current).Action;
			txtCondition.Text = ((Table)mySource.Current).Condition;
		}
		#endregion

		private void btCondition_Click(object sender, EventArgs e)
		{
			ConditionDialog dlg;
			
			dlg = new ConditionDialog();
			dlg.SetTable(((Table)mySource.Current).PrimarySchema, ((Table)mySource.Current).PrimaryTable);
			dlg.Condition = txtCondition.Text;
			if (dlg.ShowDialog() == DialogResult.OK)
				if (txtCondition.Text!=dlg.Condition)
			{
				cbAction.SelectedValue = Actions.Install;
				txtCondition.Text = dlg.Condition;
			}
		}

		private void btChange_Click(object sender, EventArgs e)
		{
			Table item;

			item = (Table)mySource.Current;
			item.SetAction((Actions)cbAction.SelectedValue, txtCondition.Text);
			myGrid.Refresh();
		}

	}
}